import javacard.framework.*;
public class aufgabe3 extends Applet{

	final static byte INS_INIT=(byte)0x10;
	  
	  final static byte INS_SEND_KEY=(byte)0x20;

	  final static byte INS_CHECK_PIN=(byte)0x18;
	  
	  final static byte[] k={0x30,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x40,
			  0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x50,
			  0x51,0x52,0x53,0x54};
	 
	  // um Punkt zu addieren 
	  final static byte INS_LOAD=(byte)0x22;
	  final static byte INS_PAY=(byte)0x24;
	 
	  // Abfallen die Transmission
	 // final static byte INS_KILL=(byte)0x26;
	 
	  
	  final static byte INS_BALANCE=(byte)0x28;
	//private final static byte BALANCE = 0x10;

	//private final static byte PAY = 0x14;
	
	//private final static byte LOAD = 0x12;

	private short value=0;
	
	//private byte[] valueByte=new byte[2];
	public void process(APDU apdu) throws ISOException {
		// TODO Auto-generated method stub
		byte[] ba=apdu.getBuffer();
		apdu.setIncomingAndReceive();
		switch(ba[ISO7816.OFFSET_INS]){
		case INS_LOAD: load(apdu) ; return;
		case INS_PAY: pay(apdu) ; return;
		case INS_BALANCE: balance(apdu) ; return;
		case INS_SEND_KEY:sendkey(apdu);return;
		case ISO7816.INS_SELECT: return;
		default: ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
		}
	}
	public static void install(byte[] Array, short a, byte b) {

		new aufgabe3();
	}
	
	public aufgabe3(){
		
		register();
	}

	public boolean select() { 
		
		return true; 
		
	}
	
	
	private void sendkey(APDU apdu)throws ISOException {
		byte[] buffer = apdu.getBuffer();
		Util.arrayCopy(k, (short) 0, buffer,ISO7816.OFFSET_CDATA, (short)24);
		apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, (short) 24);
	}

	private void balance(APDU apdu) throws ISOException{
		// TODO Auto-generated method stub
		byte[] buffer = apdu.getBuffer();
		
		//buffer[0] = (byte)(balance >> 8);
		//buffer[1] = (byte)(balance & 0xFF);
		
		Util.setShort(apdu.getBuffer(), ISO7816.OFFSET_CDATA, value);
		//ISOException.throwIt(ISO7816.SW_NO_ERROR);
		
		apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, (short) 2);
	} 


	private void pay(APDU apdu) throws ISOException{
		// TODO Auto-generated method stub
		short len = apdu.setIncomingAndReceive();
		if (len != 2) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
		byte[] buf = apdu.getBuffer();
		short val = Util.getShort(buf, ISO7816.OFFSET_CDATA);
		if (val <= 0 || (short)(value - val) < 0)
		ISOException.throwIt(ISO7816.SW_DATA_INVALID);
		value -= val;
		ISOException.throwIt(ISO7816.SW_NO_ERROR);
	}


	private void load(APDU apdu) throws ISOException{
		// TODO Auto-generated method stub
		byte[] buf = apdu.getBuffer();
		if (buf[4] != 2) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
		short len = apdu.setIncomingAndReceive();
		if (len != 2) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
		short val = Util.getShort(buf, ISO7816.OFFSET_CDATA);
		if (val <= 0 || (short)(val + value) > (short)(50000&0x7fff ))
		ISOException.throwIt(ISO7816.SW_DATA_INVALID);
		value += val;
	}

}
